<?php

// TODO: Generalizar esto a un abmcontrller
/*
 * Es un ejemplo del controlador que se ocupa de loguear y desloguear un usuario
 * La idea es heredar esta clase y extenderla a gusto.
 */
/*
 * Esto podria agregarse a Ext_Controller o como un plugin.
 */
class Ext_Controller_UserController extends Ext_Controller_SecureAction
{
    protected $_userModel = "Ext_Model_User";
    protected $_roleModel = "Ext_Model_Role";
    protected $_userRoleModel = "Ext_Model_UserRole";

    // Solo algunas acciones no requieren autenticacion, tal vez habria que partir este controller
    // en dos, pero es comodo.
    public function preDispatch()
    {
        $action = $this->getRequest()->getActionName();
        if ( $action == "login" || $action == "logout" || $action == "check" || $action == "externallogin") {
            $this->_requiresAuth = false;
        }
        
        parent::preDispatch();
    }

    public function loginAction()
    {
        // try to obtain the organization or owner for this
        // session
        $ownerId = null;
        if ( $this->_session->ownerId ) {
            $ownerId = $this->_session->ownerId;
        }
        
        // Owner can be overiden if explicitely set
        if ( $this->_request->getParam( 'ownerId' ) ) {
            $ownerId = $this->_request->getParam( 'ownerId' );
            // save it in session
            $this->_session->ownerId = $ownerId;
        }
        
        // In case no organization was specified use the
        // default from the config file.
        if ( $ownerId === null ) {
            $ownerId = $this->_config->user->login->ownerId;
        }

        $userForm = new Ext_Forms_Authentication();
        // handle login
        if ( $this->getRequest()->isPost() ) {
            if ( $userForm->isValid( $this->getRequest()->getPost() )) {
	            $auth = Zend_Auth::getInstance();
        
		        // Set up the authentication adapter
		        $authAdapter = new Ext_Generic_Authentication( 
		        	$userForm->getValue('username')
		        	, $userForm->getValue('password')
					, $this->_applicationId
		        	,$this->_db );
		        $authAdapter->setOwner( $ownerId );
		        // Attempt authentication, saving the result
		        $result = $auth->authenticate( $authAdapter );
	        
		        if ( $result->isValid() ) {
		            $this->_user = $auth->getIdentity();
		            Zend_Registry::set( 'user', $this->_user );
		            return $this->_redirect($this->_config->login->success->url );
		        } 
		        $this->addError( 'El usuario o la clave son incorrectas.' );
            } else {
            	$this->addError( 'El formulario contiene errores' );
            }
        }
    	$this->view->userForm = $userForm;
    }

    public function logoutAction()
    {
        // terminate session and send user to login
        Zend_Auth::getInstance()->clearIdentity();
        return $this->_redirect( $this->_config->login->failed->url );
    }

    

    private function validateUserId()
    {
        $userId = $this->_request->getParam( 'userId' );
        if ( empty( $userId ) ) {
            $this->addError( "UserId not found" );
            return false;
        }
        
        $userDb = Ext_Generic_Model::get( $this->_userModel, $this->_db );
        $this->view->user = $userDb->find( $userId )->current();
        if ( empty( $this->view->user ) ) {
            $this->addError( "User not found" );
            return false;
        }
        return true;
    }

    public function listAction()
    {
        $userDb = Ext_Generic_Model::get( $this->_userModel, $this->_db );
        $paginator = new Ext_Paginator( new Zend_Paginator_Adapter_Iterator( $userDb->fetchAll( null, 'end_date desc, locked asc, upper(username) asc' ) ) );
        $paginator->setCurrentPageNumber( $this->_request->getParam( "page" ) );
        $this->view->paginator = $paginator;
    }

    public function deleteAction()
    {
        if ( $this->validateUserId() ) {
            $this->view->user->delete();
        }
        $this->_redirect( $this->view->surl('user','list') );
        return;
    }

    public function undeleteAction()
    {
        if ( $this->validateUserId() ) {
            $this->view->user->unDelete();
        }
        $this->_redirect( $this->view->surl('user','list') );
        
        return;
    }

    /**
     * give to the subclasses an oportunity to set the ownerID
     *
     */
    protected function setOwnerId()
    {
        $this->view->user->owner_id = 1;
    }

    public function editAction()
    {
        $userDb = Ext_Generic_Model::get( $this->_userModel, $this->_db );
        
        $userId = $this->_request->getParam( 'userId' );
        if ( empty( $userId ) ) {
            $this->view->user = $userDb->createRow();
            $this->setOwnerId();
        } else {
            $this->view->user = $userDb->find( $userId )->current();
            if ( empty( $this->view->user ) ) {
                $this->addError( "User not found" );
                $this->_redirect( $this->view->surl('user','list') );
                return;
            }
        }
        
        $form = new Ext_Forms_EditUser( );
        $form->cancel->setLabel( 'Cancelar' )->setAttrib( 'onclick', "document.location='" .
                                                $this->view->surl('user','list') . "'");
        $form->accept->setLabel( 'Aceptar' );
        
        $data = $this->_request->getParams();
        
        if ( $this->_request->isPost() ) {
            
            if ( empty( $this->view->user->password ) ) {
                $form->password->setRequired( true )->addValidator( 'NotEmpty' );
                $form->password2->setRequired( true )->addValidator( 'NotEmpty' );
            }
            
            $isValid = $form->isValid( $data );
            
            // TODO: Make a validator for this
            if ( ! empty( $data[ "password" ] ) && ! empty( $data[ "password2" ] ) ) {
                if ( $data[ "password" ] != $data[ "password2" ] ) {
                    $this->addError( "Las claves no coinciden" );
                    $isValid = false;
                }
            }
            
            // TODO: Make a validator for this
            if ( empty( $this->view->user->username ) ) {
                $user = $userDb->getUserByName( $data[ 'username' ] );
                if ( ! empty( $user ) ) {
                    $this->addError( "El nombre del usuario ya existe" );
                    $isValid = false;
                }
            }
            
            if ( $isValid ) {
                if ( !isset( $this->extraData ) ) {
                    $this->extraData = array();
                }
                $this->extraData[ "username" ] = strtolower( trim( $data[ "username" ] ) );
                $this->extraData[ "locked" ] = $data[ "locked" ] ? 'T' : 'F';
                $this->view->user->setFromArray( $this->extraData );
                $this->view->user->changePassword( $data[ "password" ] );
                
                $this->view->user->save();
                $this->_redirect( $this->view->surl('user','list') );
            }
        }
        
        // TODO: generalizar esto
        if ( ! isset( $data[ 'username' ] ) ) {
            $data[ 'username' ] = $this->view->user->username;
        }
        $data[ 'username' ] = strtolower( trim($data[ 'username' ] ) );
        if ( ! isset( $data[ 'locked' ] ) ) {
            $data[ 'locked' ] = $this->view->user->locked == 'T';
        }
        $form->setAction( $this->view->surl('user','edit', array( 'userId' =>$this->view->user->user_id ) ) );
        $form->populate( $data );
        $this->view->form = $form;
    }

    public function roleAction()
    {
        if ( ! $this->validateUserId() ) {
            $this->_redirect( $this->view->surl('user','list') );
            return;
        }
        
        $userRoles = $this->_request->getParam( 'userRoles' );
        
        if ( $this->_request->isPost() ) {
            

            $userRoleDb = Ext_Generic_Model::get( $this->_userRoleModel, $this->_db );
            
            $this->_db->beginTransaction();
            try {
                $userId = $this->view->user->user_id;
                $userRoleDb->delete( 'user_id = ' . $userId );
                foreach ( $userRoles as $roleId ) {
                    $userRoleDb->insert( array( 
                    	'user_id' => $userId, 
                    	'role_id' => $roleId 
                    ) );
                }
                $this->_db->commit();
            } catch( Exception $e ) {
                $this->_db->rollBack();
                throw $e;
            }
            $this->_redirect( $this->view->surl('user','list') );
            
            return;
        }
        
        // Roles
        $roleDb = Ext_Generic_Model::get( $this->_roleModel, $this->_db );
        $this->view->roles = $roleDb->fetchAll();
    }

}
